<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>处理边界情况</title>
    <script src="./../vue/vue.js"></script>
</head>
<body>

    <!-- 
        1、访问根实例
            自组件中可以直接通过  $root 访问根组件的属性和方法
        2、访问父级组件实例
            $parent 这种方式可以直接触达父组件的实例，而替代 使用 props 的方式传值。但是这种方式并不好
        3、访问子组件元素或者实例
            给自组件添加一个 ref="refName" 索引名。在父组件中，通过 this.$ref.refName 来直接访问
        4、依赖注入 （大范围有效的 prop）  但是这种注入并不是双向绑定的， 在 子组件中修改这个数据，父组件中不变化。由此引入 vuex
            父组件提供 provide
            子组件注入 inject
        5、程序化的事件监听器
            $emit(eventName,)
            $on(eventName,eventHandler)
            $once(eventName,eventHandler)
            #off(eventName,eventHandler)
        6、循环引用，组件内部引用组件 不推荐

        7、模版定义的替代方案
            内联模版 inline-template 属性
            X-Template
        
        8、强制更新 
            $forceUpdate
        
        9、v-once 创建低开销的静态组件 
            组件内部包含大量的静态内容，这种情况可以用v-once 属性来确保组件内容只被计算一次，然后缓存起来

     -->

    <div id="app">

        <component-a ref="componenta"></component-a>
        <div>
            <button @click.prevent="test">按钮</button>
        </div>

        <!-- 依赖注入 -->
        <div>
            <!-- component-x 中 provide 了数据  -->
            <component-x #xsslot="{ title }">
                <component-y :title="title" #ysslot>
                    <!-- component-z 中 注入了该数据 -->
                    <component-z></component-z>
                </component-y>
            </component-x>
        </div>
        
        

    </div>
    
    <script>

        let componentA = {
            template: `
            <div>{{ $root.foo }}</div>
            `
        }
        // 依赖注入方法 
        let componentX = {
            provide: function(){
                return {
                    name: "小名"
                }
            },
            data: function(){
                return {
                    title: "你好"
                }
            },
            template: `
            <div><slot name="xsslot" v-bind:title="title"></slot></div>
            `
        }

        let componentY = {
            props: ['title'],
            template:`
            <div>
                <div>y组件的title： {{ title }}</div>
                <slot name="ysslot"></slot>
            </div>
            `
        }

        let componentZ = {
            inject: ['name'],
            template:`
            <div>z组件: {{name}}</div>
            `
        }

        let vm = new Vue({
            el: "#app",
            components: {
                'component-a': componentA,
                'component-x': componentX,
                'component-y': componentY,
                'component-z': componentZ
            },
            data: {
                foo: 1
            },
            methods: {
                test: function(){
                    console.log(this.$refs.componenta)
                }
            },
        })
    </script>
</body>
</html>